In the previous tutorial, we created a Spring boot project and build CRUD RESTful Webservices using Spring
Boot 3, Spring Data JPA (Hibernate), and MySQL database.
In this tutorial, we will see how to DTO (Data Transfer Object) pattern to transfer the data between the
Client and Server in the Spring boot application.
Data Transfer Object Design Pattern is a frequently used design pattern. It is basically used to pass data
with multiple attributes in one shot from client to server, to avoid multiple calls to a remote server.
Another advantage of using DTOs on RESTful APIs written in Java (and on Spring Boot), is that they can help
to hide implementation details of domain objects (JPA entities). Exposing entities through endpoints can
become a security issue if we do not carefully handle what properties can be changed through what
operations.
This tutorial is a continuation of Spring Boot 3 CRUD RESTful WebServices with MySQL Database
tutorial so first, you need to create a Spring Boot project with CRUD REST API's using this tutorial:
Spring Boot 3 CRUD RESTful WebServices with MySQL Database
1. Create UserDto Class
2. Change CRUD REST API's to Return UserDTO to the Client
3. Create UserMapper class
4. Change Service Layer to use UserDto
5. Test CRUD REST API's using Postman Client
package net.javaguides.springboot.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class UserDto {
private Long id;
private String firstName;
private String lastName;
private String email;
}
package net.javaguides.springboot.controller;
import lombok.AllArgsConstructor;
import net.javaguides.springboot.dto.UserDto;
import net.javaguides.springboot.entity.User;
import net.javaguides.springboot.exception.ErrorDetails;
import net.javaguides.springboot.exception.ResourceNotFoundException;
import net.javaguides.springboot.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.WebRequest;
import java.time.LocalDateTime;
import java.util.List;
@RestController
@AllArgsConstructor
@RequestMapping("api/users")
public class UserController {
private UserService userService;
// build create User REST API
@PostMapping
public ResponseEntity< UserDto> createUser(@RequestBody UserDto user){
UserDto savedUser = userService.createUser(user);
return new ResponseEntity< >(savedUser, HttpStatus.CREATED);
}
// build get user by id REST API
// http://localhost:8080/api/users/1
@GetMapping("{id}")
public ResponseEntity< UserDto> getUserById(@PathVariable("id") Long userId){
UserDto user = userService.getUserById(userId);
return new ResponseEntity< >(user, HttpStatus.OK);
}
// Build Get All Users REST API
// http://localhost:8080/api/users
@GetMapping
public ResponseEntity< List< UserDto>> getAllUsers(){
List< UserDto> users = userService.getAllUsers();
return new ResponseEntity< >(users, HttpStatus.OK);
}
// Build Update User REST API
@PutMapping("{id}")
// http://localhost:8080/api/users/1
public ResponseEntity< UserDto> updateUser(@PathVariable("id") Long userId,
@RequestBody UserDto user){
user.setId(userId);
UserDto updatedUser = userService.updateUser(user);
return new ResponseEntity< >(updatedUser, HttpStatus.OK);
}
// Build Delete User REST API
@DeleteMapping("{id}")
public ResponseEntity< String> deleteUser(@PathVariable("id") Long userId){
userService.deleteUser(userId);
return new ResponseEntity< >("User successfully deleted!", HttpStatus.OK);
}
}
Let's create a UserMapper class to convert the User entity to UserDto and UserDto to the User entity:
package net.javaguides.springboot.mapper;
import net.javaguides.springboot.dto.UserDto;
import net.javaguides.springboot.entity.User;
public class UserMapper {
// Convert User JPA Entity into UserDto
public static UserDto mapToUserDto(User user){
UserDto userDto = new UserDto(
user.getId(),
user.getFirstName(),
user.getLastName(),
user.getEmail()
);
return userDto;
}
// Convert UserDto into User JPA Entity
public static User mapToUser(UserDto userDto){
User user = new User(
userDto.getId(),
userDto.getFirstName(),
userDto.getLastName(),
userDto.getEmail()
);
return user;
}
}
package net.javaguides.springboot.service;
import net.javaguides.springboot.dto.UserDto;
import net.javaguides.springboot.entity.User;
import java.util.List;
public interface UserService {
UserDto createUser(UserDto user);
UserDto getUserById(Long userId);
List< UserDto> getAllUsers();
UserDto updateUser(UserDto user);
void deleteUser(Long userId);
}
package net.javaguides.springboot.service.impl;
import lombok.AllArgsConstructor;
import net.javaguides.springboot.dto.UserDto;
import net.javaguides.springboot.entity.User;
import net.javaguides.springboot.mapper.UserMapper;
import net.javaguides.springboot.repository.UserRepository;
import net.javaguides.springboot.service.UserService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
@AllArgsConstructor
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
@Override
public UserDto createUser(UserDto userDto) {
// Convert UserDto into User JPA Entity
User user = UserMapper.mapToUser(userDto);
User savedUser = userRepository.save(user);
// Convert User JPA entity to UserDto
UserDto savedUserDto = UserMapper.mapToUserDto(savedUser);
return savedUserDto;
}
@Override
public UserDto getUserById(Long userId) {
Optional< User> optionalUser = userRepository.findById(userId);
User user = optionalUser.get();
return UserMapper.mapToUserDto(user);
}
@Override
public List< UserDto> getAllUsers() {
List< User> users = userRepository.findAll();
return users.stream().map(UserMapper::mapToUserDto)
.collect(Collectors.toList());
}
@Override
public UserDto updateUser(UserDto user) {
User existingUser = userRepository.findById(user.getId()).get();
existingUser.setFirstName(user.getFirstName());
existingUser.setLastName(user.getLastName());
existingUser.setEmail(user.getEmail());
User updatedUser = userRepository.save(existingUser);
return UserMapper.mapToUserDto(updatedUser);
}
@Override
public void deleteUser(Long userId) {
userRepository.deleteById(userId);
}
}
Request URL: http://localhost:8080/api/users
HTTP Method: POST
Request Body:
{
"firstName": "ramesh",
"lastName":"fadatare",
"email": "ramesh@gmail.com"
}
Request URL: http://localhost:8080/api/users/1
HTTP Method: GET
Refer to this screenshot to test GET User REST API:
Request URL: http://localhost:8080/api/users/1
HTTP Method: PUT
Request Body:
{
"firstName": "ram",
"lastName":"fadatare",
"email": "ram@gmail.com"
}
Refer to this screenshot to test the Update User REST API:
Request URL: http://localhost:8080/api/users
HTTP Method: GET
Refer to this screenshot to test GET All User REST API:
Request URL: http://localhost:8080/api/users/1
HTTP Method: DELETE
Refer to this screenshot to test Delete User REST API:
The source code of this tutorial is available on my GitHub repository at Spring Boot CRUD RESTful WebServices
In this tutorial, we have seen how to use DTO (Data Transfer Object) pattern to transfer the database between the client and server in the Spring boot application.